package io.gitee.tooleek.lock.spring.boot.core;

import io.gitee.tooleek.lock.spring.boot.enumeration.LockType;
import io.gitee.tooleek.lock.spring.boot.exception.LockFailException;
import io.gitee.tooleek.lock.spring.boot.factory.ServiceBeanFactory;
import io.gitee.tooleek.lock.spring.boot.service.LockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @version : 1.0
 * @description: 分布式锁帮助类，借助于lock-spring-boot-starter 框架，使用其内部api来实现redis分布式锁
 * @author: tianwen
 * @create: 2020/5/16 12:38
 **/
@Component
public class TooLeekLookHelper {

    ThreadLocal<LockService> threadLocal = new ThreadLocal<>();

    @Autowired
    private ServiceBeanFactory serviceBeanFactory;

    /**
     * 分布式锁工具类 借助于 lock-spring-boot-starter api
     *
     * @param key       redis的键 不可为空
     * @param lockType  锁的类型 不可为空
     * @param leaseTime 加锁时间，超过该时长自动解锁 不可为空
     * @param waitTime  等待锁时间 不可为空
     * @param timeUnit  锁时长单位 不可为空
     */
    public void lock(String key, LockType lockType, Integer leaseTime, Integer waitTime, TimeUnit timeUnit) {
        try {
            LockService lockService = serviceBeanFactory.getService(lockType);
            threadLocal.set(lockService);
            LockKey lockKey = LockKey.newBuilder().appendKey(key).leaseTime(leaseTime).waitTime(waitTime).timeUnit(timeUnit).build();
            lockService.setLockKey(lockKey);
            lockService.lock();
        } catch (Exception e) {
            e.printStackTrace();
            threadLocal.remove();
            throw new LockFailException("锁获取异常异常", e);
        }

    }

    public void unLock() {
        threadLocal.get().release();
        threadLocal.remove();
    }

}
